package com.tinysand.advert.index.impl;

import com.tinysand.advert.index.IndexAware;
import com.tinysand.advert.utils.CommonUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListSet;

/**
 * Created By TINY
 * Create Time 2020/2/27
 **/
@Component
@SuppressWarnings("all")
public class KeywordIndex
        implements IndexAware<String, Set<Long>> {

    // 反向索引 <keywords, unitId>
    private static Map<String, Set<Long>> keywordUnitMap;
    // 正向索引 <unitId, keywords>
    private static Map<Long, Set<String>> unitKeywordMap;

    static {
        keywordUnitMap = new ConcurrentHashMap<>();
        unitKeywordMap = new ConcurrentHashMap<>();
    }

    @Override
    public Set<Long> get(String key) {
        if (StringUtils.isEmpty(key)) { return Collections.emptySet(); }

        Set<Long> result = keywordUnitMap.get(key);
        if (result == null) { return Collections.emptySet(); }

        return result;
    }

    @Override
    public void add(String key, Set<Long> value) {
        Set<Long> unitIdSet = CommonUtils.getOrCreate(
                key, keywordUnitMap, ConcurrentSkipListSet::new);

        unitIdSet.addAll(value);

        for (Long unitId : value) {
            Set<String> keywordSet = CommonUtils.getOrCreate(
                    unitId, unitKeywordMap, ConcurrentSkipListSet::new);
            keywordSet.add(key);
        }
    }

    @Override
    public void update(String key, Set<Long> value) {
        // 不支持更新操作
    }

    @Override
    public void delete(String key, Set<Long> value) {
        Set<Long> unitIdSet = CommonUtils.getOrCreate(
                key, keywordUnitMap, ConcurrentSkipListSet::new);

        unitIdSet.removeAll(value);

        for (Long unitId : value) {
            Set<String> keywordSet = CommonUtils.getOrCreate(
                    unitId, unitKeywordMap, ConcurrentSkipListSet::new);
            keywordSet.remove(key);
        }
    }

    /* 判断推广单元中是否包含指定关键字约束 */
    public boolean match(Long unitId, List<String> keywords) {
        // 存在 unitId 对应的推广单元并且推广单元中包含的关键字不为空
        if (unitKeywordMap.containsKey(unitId)
                && CollectionUtils.isNotEmpty(unitKeywordMap.get(unitId))) {
            Set<String> unitKeywords = unitKeywordMap.get(unitId);

            return CollectionUtils.isSubCollection(keywords, unitKeywords);
        }
        return false;
    }
}
